package com.googlecode.milib.tools {
	import com.googlecode.milib.base.IMLBroadcasterListener;
	import com.googlecode.milib.base.MLBroadcastClass;
	import com.googlecode.milib.service.MLLoader;
	import com.googlecode.milib.service.singleton.EnterFrameService;
	import com.googlecode.milib.vo.MLEventInfo;

	import flash.display.AVM1Movie;
	import flash.display.DisplayObjectContainer;
	import flash.net.LocalConnection;
	import flash.net.URLRequest;

	/**
	 * @author Marek Brun @ MindChili
	 */
	public class AVM1MovieProxySwf extends MLBroadcastClass implements IMLBroadcasterListener {
		
		public const event_TargetSWFLoaded : String = 'TargetSWFLoaded';
		
		private var AVM1SWFHolder:DisplayObjectContainer;
		private var AVM1ProxySWFURL:String;
		private var AVM1SWFURL:String;
		private var loader:MLLoader;
		private var avm1ProxyMovie:AVM1Movie;
		private var localConnectionSuffix:String;
		private var lc:LocalConnection;
		private var lcFrom:LocalConnection;
		private var isTargetSWFLoaded:Boolean;
		private var countSendings:Number=0;
		private var actions:Array=[];
		
		public function AVM1MovieProxySwf(AVM1SWFHolder:DisplayObjectContainer, AVM1SWFURL:String, AVM1ProxySWFURL:String="avm1proxy.swf", localConnectionSuffix:String='') {
			this.AVM1SWFHolder=AVM1SWFHolder;
			this.AVM1SWFURL=AVM1SWFURL;			this.AVM1ProxySWFURL=AVM1ProxySWFURL;
			this.localConnectionSuffix=localConnectionSuffix;
			
			lc=new LocalConnection();
			
			lcFrom=new LocalConnection();
			lcFrom.client=this;
			lcFrom.connect('fromAVM1Proxy');
			
			loader=new MLLoader();
			loader.setup(new URLRequest(AVM1ProxySWFURL+'?swfToLoadURL='+AVM1SWFURL+'&lcSuffix='+localConnectionSuffix));
			loader.addListener(this);
			loader.start();
			
		}
		
		public function setVariable(name:String, value:*):AVM1MovieProxySwfCall {
			if(!isTargetSWFLoaded){
				throw new Error('Can\'t set variable until target AVM1 swf is loaded. Please use that method after "TargetSWFLoaded" event');
			}
			var action:AVM1MovieProxySwfCall=new AVM1MovieProxySwfCall();
			action.start();
			countSendings++;
			actions[countSendings]=action;
			lc.send('toAVM1Proxy'+localConnectionSuffix, 'setVariable', [countSendings, name, value]);
			return action;
		}
		
		public function getVariable(name:String):AVM1MovieProxySwfCall {
			if(!isTargetSWFLoaded){
				throw new Error('Can\'t set variable until target AVM1 swf is loaded. Please use that method after "TargetSWFLoaded" event');
			}
			var action:AVM1MovieProxySwfCall=new AVM1MovieProxySwfCall();
			action.start();
			countSendings++;
			actions[countSendings]=action;
			lc.send('toAVM1Proxy'+localConnectionSuffix, 'getVariable', [countSendings, name]);
			return action;
		}
		
		public function callFunction(functionName:String, args:Array=null):AVM1MovieProxySwfCall {
			if(!isTargetSWFLoaded){
				throw new Error('Can\'t call method until target AVM1 swf is loaded. Please use that method after "TargetSWFLoaded" event');
			}
			var action:AVM1MovieProxySwfCall=new AVM1MovieProxySwfCall();
			action.start();
			countSendings++;
			actions[countSendings]=action;
			lc.send('toAVM1Proxy'+localConnectionSuffix, 'callFunction', [countSendings, functionName, args]);
			return action;
		}
		
		public function targetSWFLoaded():void {
			isTargetSWFLoaded=true;
			broadcastEvent(event_TargetSWFLoaded);
		}
		
		public function executedAction(actionID:Number, returnData:*):void {
			if(isNaN(actionID)){ return; }
			AVM1MovieProxySwfCall(actions[actionID]).returnData=returnData;
			AVM1MovieProxySwfCall(actions[actionID]).finish();
		}
		
		public function trace(text:String):void {
			dbg.log('log from AVM1ProxySWF:'+text);
		}
		
		public function proxyLoadingFinished():void {
			avm1ProxyMovie=AVM1Movie(loader.loader.content);
			AVM1SWFHolder.addChild(avm1ProxyMovie);
		}
		
//********************************************************************************************
//		events for AMV1ProxySwf
//********************************************************************************************
		public function onEvent(ev:MLEventInfo):void {
			switch(ev.hero){
				case loader:
					switch(ev.event) {
						case loader.event_ActionFinish:
							EnterFrameService.getInstance().callMethodAfterFrames(2, proxyLoadingFinished);
						break;
					}
				break;
			}
		}
	}
}
